<?php
/**
 * DMFramework
 * 
 * @license Copyright 2012 Dillen Meijboom under the Apache license version 2.0 (http://apache.org/licenses/LICENSE-2.0)
 * @author Dillen Meijboom <info@dillenm.nl>
 * @url http://dmframework.nl
 */

/**
 * The HTTP auth class.
 * 
 * @license Copyright 2012 Dillen Meijboom under the Apache license version 2.0 (http://apache.org/licenses/LICENSE-2.0)
 * @author Dillen Meijboom <info@dillenm.nl>
 * @package System.Library
 */
class Dmf_Auth_Http
{
    /**
     * The realm displayed at the login screen
     * 
     * @var string 
     */
    private $_realm;
    
    /**
     * All (local) users
     * 
     * @var array 
     */
    private $_userData;
    
    /**
     * Constructor
     * 
     * @param string $realm 
     */
    public function __construct( $realm )
    {
        $this->_realm = $realm;
    }
    
    /**
     * Set all login data
     * 
     * @param array $data 
     */
    public function setLoginData( $data )
    {
        $this->_userData = $data;
    }
    
    /**
     * Read a htpasswd file
     * 
     * @param string $filename
     * @throws Exception 
     */
    public function readFile( $filename )
    {
        if ( ! file_exists( $filename ) )
        {
            throw new Exception( 'File: "' . $filename . '" does not exist.' );
        }
        
        foreach( explode( "\n", file_get_contents( $filename ) ) as $line )
        {
            $data = explode( ':', $line );
            
            $this->addUser( $data['0'], $data['1'] );
        }
    }
    
    /**
     * Add a user to the userData, password can either be md5'd or not.
     * 
     * @param string $user
     * @param string $pass 
     */
    public function addUser( $user, $pass )
    {
        $this->_userData[ $user ] = $pass;
    }
    
    /**
     * Activate the login screen and show headers.
     * 
     * @param boolean $terminate
     * @return boolean
     * @throws Exception 
     */
    public function authenticate( $terminate = false )
    {
        if ( ! isset( $_SERVER['PHP_AUTH_USER'] ) )
        {
            header('HTTP/1.1 401 Unauthorized');
            header('WWW-Authenticate: Basic realm="'. $this->_realm . '"');
            
            if ( $terminate === true )
            {
                throw new Exception( 'Unauthorized request, please authenticate.', 401 );
            }
            else
            {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Get loggedin user
     * 
     * @return mixed 
     */
    public function getUser()
    {
        return isset( $_SERVER['PHP_AUTH_USER'] ) ? $_SERVER['PHP_AUTH_USER'] : false;
    }
    
    /**
     * Check if the user is logged in (and display login screen when not).
     * 
     * @param boolean $terminate
     * @return boolean
     * @throws Exception 
     */
    public function isLoggedIn( $terminate = false )
    {
        if ( ! isset( $_SERVER['PHP_AUTH_USER'] ) )
        {
            $this->authenticate();
        }
        
        foreach( $this->_userData as $username => $password )
        {
            if ( $_SERVER['PHP_AUTH_USER'] == $username && ( $_SERVER['PHP_AUTH_PW'] == $password || md5( $_SERVER['PHP_AUTH_PW'] ) == $password ) )
            {
                return true;
            }
        }
        
        if ( $terminate === true )
        {
            throw new Exception( 'Unauthorized request, please authenticate.', 401 );
        }
        else
        {
            return false;
        }
    }
    
    /**
     * Clear HTTP login data
     */
    public function logoff()
    {
        header('HTTP/1.1 401 Unauthorized');
    }
}